package com.bingxue.edu.management.system.service;

import cn.hutool.core.bean.BeanUtil;
import com.bingxue.edu.framework.common.util.ValidationUtils;
import com.bingxue.edu.framework.mybatis.base.BaseService;
import com.bingxue.edu.management.system.mapper.DictItemMapper;
import com.bingxue.edu.management.system.mapper.DictMapper;
import com.bingxue.edu.management.system.model.entity.Dict;
import com.bingxue.edu.management.system.model.req.DictCreateReq;
import com.bingxue.edu.management.system.model.req.DictUpdateReq;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

import static com.bingxue.edu.management.system.model.entity.table.DictItemTableDef.DICT_ITEM;
import static com.bingxue.edu.management.system.model.entity.table.DictTableDef.DICT;


@Slf4j
@Service
@RequiredArgsConstructor
public class DictService extends BaseService<DictMapper, Dict> {
    private final DictMapper dictMapper;
    private final DictItemMapper dictItemMapper;


    /**
     * 新增字典数据
     *
     * @param req {DictCreateReq}
     * @return {boolean}
     */
    public boolean addDict(DictCreateReq req) {
        String name = req.getName();
        String code = req.getCode();
        //新增时，判断名称和编码是否已存在，如存在则抛出BusinessException
        ValidationUtils.throwIf(this.isNameExists(name, null), "新增失败，[{}] 已存在", name);
        ValidationUtils.throwIf(this.isCodeExists(code, null), "新增失败，[{}] 已存在", code);
        Dict dict = BeanUtil.copyProperties(req, Dict.class);
        return this.save(dict);
    }

    /**
     * 更新字典数据
     *
     * @param req {DictUpdateReq}
     * @param id  {String}
     */
    public void updateDict(DictUpdateReq req, String id) {
        String name = req.getName();
        Dict oldDict = super.getById(id);
        //判断该字典是否存在
        ValidationUtils.throwIfNull(oldDict, "该字典不存在");
        //当名称被修改时，判断该名称是否已存在，如存在则抛出BusinessException异常
        if (!oldDict.getName().equals(name)) {
            ValidationUtils.throwIf(this.isNameExists(name, null), "修改失败，[{}] 已存在", name);
        }
        Dict dict = BeanUtil.copyProperties(req, Dict.class);
        dict.setId(id);
        this.updateById(dict);
    }

    /**
     * 删除字典
     *
     * @param ids {List<String>}
     */
    public void deleteDict(List<String> ids) {
        List<Dict> dicts = this.listByIds(ids);
        for (Dict dict : dicts) {
            ValidationUtils.throwIf(dict.getReserved(), "删除失败，[{}]为预置字典", dict.getName());
        }
        QueryWrapper queryWrapper = QueryWrapper.create().where(DICT_ITEM.DICT_ID.in(ids));
        ValidationUtils.throwIf(!dictItemMapper.selectListByQuery(queryWrapper).isEmpty(),"该字典下存在字典项");
        this.removeByIds(ids);
    }


    /**
     * 判断name是否已存在
     *
     * @param name {String}
     * @param id   {String}
     * @return {boolean}
     */
    public boolean isNameExists(String name, String id) {
        //方法3 查询字典id不为id且name为name的数据是否存在
        return this.queryChain().where(DICT.NAME.eq(name)).and(DICT.ID.ne(id)).exists();

    }

    /**
     * 判断字典Code是否已存在
     *
     * @param code {String}
     * @param id   {String}
     * @return {boolean}
     */
    public boolean isCodeExists(String code, String id) {
        return this.queryChain().where(DICT.CODE.eq(code)).and(DICT.ID.ne(id)).exists();
    }

    /**
     * 根据id获取Dict字典数据
     *
     * @param ids {List<String>}
     * @return {List<Dict>}
     */
    public List<Dict> getListByIds(List<String> ids) {
        return this.queryChain().where(DICT.ID.in(ids)).list();
    }

    public Dict getEntityByCode(String code) {
        QueryWrapper queryWrapper  =QueryWrapper.create()
                        .select(DICT.ALL_COLUMNS)
                        .where(DICT.CODE.eq(code));
        return dictMapper.selectOneByQuery(queryWrapper);
    }
}
